import Data.List
import Debug.Trace

listCompare :: (Show t, Num t, Ord t) => [t] -> [t] -> Ordering
listCompare [] [] = EQ
listCompare [] _ = LT
listCompare _ [] = GT
listCompare (x:xs) (y:ys) = trace ("comparando: " ++ show x ++ ", " ++ show y) $ if x == y
                                                                                                                           then listCompare xs ys
                                                                                                                           else if x < y
                                                                                                                                      then LT
                                                                                                                                      else GT

listaValida :: (Num t, Ord t) => [t] -> Bool   
listaValida [] = True
listaValida [x] = True
listaValida (x:xs) = x < head xs && listaValida xs

lengthIgual ::  Int -> [t] -> Bool
lengthIgual n xs = length xs == n

filtroListaValida :: (Num t, Ord t) => [[t]] -> [[t]]
filtroListaValida xs = filter (listaValida) xs

filtroTamanho :: (Num t, Ord t) => Int -> [[t]] -> [[t]]
filtroTamanho n xs = filter (lengthIgual n) (filtroListaValida xs)

comb :: (Num t, Ord t) => [t] -> Int -> [[t]]
comb xs n = filtroTamanho n (subsequences xs)

combFR :: (Num t, Ord t) => [t] -> Int -> [[t]]
combFR xs 0 = [[]]
combFR xs n = comb xs n ++ combFR xs (n - 1)

combF :: (Num t, Ord t) => [t] -> [[t]]
combF xs = combFR xs (length xs)

combFRev :: (Num t, Ord t) => [t] -> [[t]]
combFRev xs = reversea $ combF xs

produtoDasSomas :: (Num t) => [[t]] -> t
produtoDasSomas xs = product (map (sum) xs)

somaDosProdutos :: (Num t) => [[t]] -> t
somaDosProdutos xs = sum (map (product) xs)